<?php

namespace Modules\Coupon\Entities;

use Modules\Coupon\Entities\UserCoupon;
use Modules\Core\Entities\BaseEntity as Model;
use Modules\Order\Entities\BaseOrder as Order;
use ThrowException;
use Setting;
use DB;

class Coupon extends Model
{
    protected $guarded = [];
    protected $table = 'coupons';

    static public $resourceName = '优惠券';

    protected $appends = ['usable_range_text'];

    protected $casts = [
        'usable_ids' => 'array',
        'to_use_link' => 'json'
    ];

    public function user_coupons()
    {
    	return $this->hasMany('\Modules\Coupon\Entities\UserCoupon', 'coupon_id');
    }

    public function user_group()
    {
        return $this->belongsTo('\Modules\User\Entities\UserGroup', 'user_group_id');
    }

    public function scopeAvailable($query)
    {
        return $query->status('on');
    }

    public function scopeStatus($query, $type)
    {
        $status = $type === 'on' ? 1 : 0;
        return $query->where('status', $status);
    }

    public function getUsableRangeTextAttribute()
    {
        $map = [
            0 => '通用',
            1 => '指定盲盒可用',
            2 => '指定商品可用',
            3 => '指定VIP套餐',
            4 => '指定活动',
            5 => '指定一番赏',
            6 => '指定福袋',
            20 => '指定抽赏',
            21 => '指定擂台'
        ];

        return @$map[$this->usable_range_type] ?: '未知';
    }

    public function pushTo($user, $pushType = 'manual', $throwException = true)
    {
        if ($this->stock <= 0) {
            $throwException && ThrowException::Conflict('券已领光了哦~');
            return false;
        }

        // 是否限制领取条件
        if ($this->user_group_id && $this->user_group) {
            $this->user_group->isPassed($user) ?: ThrowException::Conflict('暂不满足领取条件~');
        }

        
    	// 检查权限及当前优惠券是否可以push给用户
    	if ($user->coupons()->where('coupon_id', $this->id)->count() >= $this->usable_per_user) {
    		$throwException && ThrowException::Conflict('已领取过此券');
            return false;
        }

        // 每日流水类型券 当日已领的券要减去对应消耗的流水
        if ( strstr($this->title, '当日流水每满') != false ){
            $value = str_replace(array('当日流水每满', ' ', '（测试）', '(测试)'), '', $this->title);
            $value = $value*1;
            $t_d = date('Y-m-d');
            $orders = Order::paid()->where([
                'type' => 'activity',
                'user_id' => $user->id,
                ['completed_at', '>', $t_d],
                ['user_id', '>', 500]
            ])->whereIn('status', [8,9])
            ->first(\DB::raw('sum(redpack_discount + pay_money_price) amount'));

            // 当日已领
            $count_today = $user->coupons()->where('coupon_id', $this->id)->where('created_at', '>', $t_d)->count();

            if ( $orders->amount/100 < $value*($count_today+1) ){
                ThrowException::Conflict("当日已领 $count_today 张, 继续消费 ".($value*($count_today+1)-$orders->amount/100)." 后可再次领取");
            }
        }

        // 如果是用户手动领取并且此券是需要积分兑换
        if ($pushType == 'manual' && $this->score_price) {
            if (!$user->asset('score')->out($this->score_price, [
                'description' => '兑换优惠券-' . $this->title ,
            ])) {
                $throwException && ThrowException::Conflict(Setting::scoreAlias() . '不足哦~');
                return false;
            };
        }

    	$user->coupons()->save(UserCoupon::initWith($this, $pushType));

        $this->stock -= 1;
        $this->sales += 1;
        $field = 'sale_by_' . $pushType;
        $this->$field += 1;
        $this->save();

    	return true;
    }

    // 对单个sku是否可用
    public function isUsableForSku($orderSku)
    {
        // 全场通用
        if ($this->usable_range_type === 0)
            return true;

        // \Log::error($orderSku->getInfo());

        // 指定盲盒
        if ($this->usable_range_type === 1) {
            return $orderSku->node_type === 'box' && in_array($orderSku->node_id, $this->usable_ids);
        }

        // 指定盲盒
        if ($this->usable_range_type === 2) {
            return $orderSku->node_type === 'product' && in_array($orderSku->node_id, $this->usable_ids);
        }

        // 指定vip套餐
        if ($this->usable_range_type === 3) {
            return $orderSku->node_type === 'vip' && in_array($orderSku->node_id, $this->usable_ids);
        }

        // 指定vip套餐
        if ($this->usable_range_type === 4) {
            // \Log::error($orderSku->product_id);
            // \Log::error($orde)
            return $orderSku->node_type === 'activity' && in_array($orderSku->node_id, $this->usable_ids);
        }

        // 指定一番赏
        if ($this->usable_range_type === 5) {
            // \Log::error($orderSku->product_id);
            // \Log::error($orde)
            return $orderSku->node_type === 'yifanshang' && in_array($orderSku->node_id, $this->usable_ids);
        }

        // 指定福袋
        if ($this->usable_range_type === 6) {
            // \Log::error($orderSku->product_id);
            // \Log::error($orde)
            return $orderSku->node_type === 'fudai' && in_array($orderSku->node_id, $this->usable_ids);
        }

        // 指定抽赏
        if ($this->usable_range_type === 20) {
            // \Log::error($orderSku->product_id);
            // \Log::error($orde)
            $res = DB::select("select id from choushang_activity where title IN ( select title from choushang_activity where id in (".implode(',', $this->usable_ids).") ) ");
            if ( $res ){
                $res = object_to_array($res);
                return $orderSku->node_type === 'choushang' && in_array($orderSku->node_id, array_column($res, 'id'));
            }

            return false;
        }

        // 指定擂台
        if ($this->usable_range_type === 21) {
            // \Log::error($orderSku->product_id);
            // \Log::error($orde)
            $res = DB::select("select id from leitai_activity where title IN ( select title from leitai_activity where id in (".implode(',', $this->usable_ids).") ) ");
            if ( $res ){
                $res = object_to_array($res);
                return $orderSku->node_type === 'leitai' && in_array($orderSku->node_id, array_column($res, 'id'));
            }

            return false;
        }

    }

    // 计算一个订单中可以参与此券的优惠总价
    public function calcDiscountOrderPrice($orderSkus)
    {
        $that = $this;
        $orderSkus = array_filter($orderSkus, function ($item) use ($that) {
            return $that->isUsableForSku($item);
        });

        // 计算有效金额
        $sum = 0;
        foreach ($orderSkus as $orderSku) {
            $sum += $orderSku->discount_money_price * $orderSku->total;
        }

        return $sum;
    }

    // 计算一个订单中可以参与此券的sku数量
    public function calcDiscountSkuTotal($orderSkus)
    {
        $total = 0;
        foreach ($orderSkus as $sku) {
            if ($this->isUsableForSku($sku)) {
                $total += $sku->total;
            }
        }

        return $total;
    }

    // 计算此优惠券是否适合某个订单
    public function isUsable($order)
    {
        // 先排除包邮券
        if ($this->discount_type === 2 && $order->carriage <= 0) 
            return false;

        $orderSkus = $order->skusTemp;
        $sum = $this->calcDiscountOrderPrice($orderSkus);

        if ($this->discount_type === 2) {
            return $sum >= ($this->minimum_money ?: 0);
        }
        else {
            return $sum >= ($this->minimum_money ?: 1);
        }
    }

    // 计算此优惠券是否适合某个订单sku集
    public function isUsableForSkus($orderSkus)
    {
        $sum = $this->calcDiscountOrderPrice($orderSkus);

        // 不满足最低使用金额
        if ($sum < ($this->minimum_money ?: 0)) {
            return false;
        }

        // 是否有满足的sku
        if ($this->calcDiscountSkuTotal($orderSkus) === 0) {
            return false;
        }

        return true;
    }

    // 是否可领取
    public function isAvailable($user)
    {
        return $this->where('status', 1);
    }

    // 用户是否领取过此券
    public function isPickedBy($user)
    {
        return $user->coupons()->where('coupon_id', $this->id)->first();
    }

    // 计算某个订单可抵扣金额
    public function calcDiscountMoney($order)
    {
        $skus = $order->skusTemp;

        $money = 0;

        if ($this->discount_type === 0) {
            // 现金券
            $money = $this->discount_money;
        }
        elseif ($this->discount_type === 1) {
            // 折扣券
            $calcDiscount = $this->calcDiscountOrderPrice($skus) * (100 - $this->discount_rate) / 100;

            $money = $calcDiscount;
        }
        elseif ($this->discount_type === 2) {
            // 包邮券
            $money = $order->carriage;
        }
        elseif ($this->discount_type === 3) {
            // 兑换券
            // 如有多个sku， 兑换券的策略是只兑换第1个sku数量为1的价值金额
            foreach ($skus as $sku) {
                if ($this->isUsableForSku($sku)) {
                    $money = $sku->discount_money_price;
                    break;
                }
            }
        }

        return floor($money);
        // return $money > $order->pay_price ? $order->pay_price : $money;
    }
}
